import { Controller } from 'egg';
import moment from 'moment';
import crypto from 'crypto';
import qs from 'qs';

const generateToken = function() {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(48, (err, buffer) => {
      if (err) {
        reject(err);
      } else {
        resolve(buffer.toString('hex'));
      }
    });
  });
};

export default class PassportController extends Controller {

  /**
     * 登录验证
     */
  async login() {
    const {
      body: { code, userInfo },
    } = this.ctx.validateReq('wx.login');

    const id = this.ctx._shop.id;

    const shop = await this.ctx.service.shop.merchant.model.findOne({
      where: { id },
    });
    const wxApp = this.ctx.app.config.wxApp;
    const { appid, secret, partner_key } = shop;
    const params = { appid, secret, js_code: code, grant_type: 'authorization_code' };

    try {
      const { data } = await this.ctx.curl(`${wxApp.login}?${qs.stringify(params)}`,
        {
          method: 'GET',
          dataType: 'json',
          timeout: 60000,
        },
      );

      const { openid, session_key, unionid } = data || {};
      if (openid) {
        const {
          // avatarUrl,
          gender,
          nickName,
        } = userInfo || {};

        const { ip } = this.ctx;
        const token = await generateToken();
        const time = moment().unix();

        const user = {
          user_id: openid,
          last_login_ip: ip,
          last_login_time: time,
          user_level_id: 0,
          register_ip: ip,
          weixin_unionid: unionid,
          weixin_session_key: session_key,
          nickname: nickName,
          gender,
          token,
          register_time: time,
          token_update_time: time,
          avatar: '',
        };
        const [ result ] = await this.ctx.model.MUser.findOrCreate({
          where: { user_id: openid, is_delete: 0 },
          defaults: user,
        });
        const passToken = this.app.jwt.sign({ openid, session_key }, this.config.jwt.secret);
        if (result) {
          const { user_id } = result || {};
          return this.ctx.success({
            data: {
              user_id,
              partner_key,
              token: passToken,
            },
          });
        }
      }
      this.ctx.failure();
    } catch (e) {
      console.log(e);
      this.ctx.failure();
    }
  }
  async userInfo() {
    const { openid } = this.ctx.state.user;
    const result = await this.ctx.model.MUser.findOne({
      where: { user_id: openid, is_delete: 0 },
    });
    if (result) {
      this.ctx.success({
        data: result,
      });
    }

  }


  async update() {
    const { openid } = this.ctx.state.user;
    const result = await this.ctx.model.MUser.findOne({
      where: { user_id: openid },
    });

    if (result) {
      const { avatarUrl, nickName } = this.ctx.request.body;
      const updateParams = {};
      if (avatarUrl) {
        Object.assign(updateParams, { avatar: avatarUrl });
      }
      if (nickName) {
        Object.assign(updateParams, { nickname: nickName });
      }
      const updated = await this.ctx.model.MUser.update(updateParams, { where: { user_id: result.user_id } });
      if (updated) {
        this.ctx.success({
          data: updated,
        });
      }
    }

  }
}
